package com.pi.pro.xcmg.am.rf.web.cust.controller;



import com.fasterxml.jackson.annotation.JsonView;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.pi.common.utils.StringUtils;
import com.pi.framework.core.bean.PageResult;
import com.pi.framework.core.bean.Result;
import com.pi.framework.core.service.ICrudService;
import com.pi.framework.core.util.DateUtils;
import com.pi.framework.core.util.SecurityUtils;
import com.pi.pro.xcmg.am.common.XcmgAmConstants;
import com.pi.pro.xcmg.am.common.vo.act.WaveShipHeadDto;
import com.pi.pro.xcmg.am.common.vo.act.WaveShipLineDto;
import com.pi.pro.xcmg.am.was.fac.service.WasCustomWorkService;
import com.pi.pro.xcmg.am.was.fac.service.WcsCustomWorkService;
import com.pi.wms.common.WmsConstants;
import com.pi.wms.dto.act.ShipHeaderDto;
import com.pi.wms.dto.base.LocationLineDto;
import com.pi.wms.dto.outbound.SoStorageShipMatchDto;
import com.pi.wms.entity.*;
import com.pi.wms.fac.LocationResolver;
import com.pi.wms.rf.api.controller.BaseApiController;
import com.pi.wms.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;


@Api(value = "发运管理")
@RestController
@RequestMapping("/outbound/ship/ca")
public class CustApplyShipApiController extends BaseApiController<TwtActAllocationList, Long> {

	@Autowired
	private MaterialService materialService;
	@Autowired
	private LocationResolver locationResolver;
	@Autowired
	private AllocationService allocationService;

	@Autowired
	private WaveService waveService;

	@Autowired
	private WasCustomWorkService wasCustomWorkService;

	@Autowired
	private WcsCustomWorkService wcsCustomWorkService;

	//
	private Cache<Long, String> locationZoneCache= CacheBuilder.newBuilder().expireAfterWrite(20, TimeUnit.MINUTES).build();


	@Override
	protected ICrudService<TwtActAllocationList, Long> getCrudService() {
		return this.allocationService;
	}
	
	@JsonView(value = { PageResult.View.class })
	@ApiOperation("查询指定托盘的发运明细")
	@GetMapping("/query")
	public Result query(
            @ApiParam(name = "containnumber") @RequestParam(name = "containnumber", required=true) String containnumber,
            @ApiParam(name = "documentnumber") @RequestParam(name = "documentnumber", required=false) String documentnumber,
            @ApiParam(name = "allocationid") @RequestParam(name = "allocationid", required=false) String allocationid,
            @ApiParam(name = "documentmode") @RequestParam(name = "documentmode", required=false) String documentmode,
			@ApiParam(name = "usercode") @RequestParam(name = "usercode", required=false) String usercode) {
		
		if ((StringUtils.isNullOrBlank(containnumber))
                && (StringUtils.isNullOrBlank(documentnumber))
                && (StringUtils.isNullOrBlank(allocationid))  ){
			return resultError(501, "请指定托盘码或单号");
		}
		if (documentnumber!=null){
			documentnumber=documentnumber.trim();
			if ((documentnumber.indexOf("x")>=0) || (documentnumber.indexOf("X")>=0)){
				documentnumber=documentnumber.replace("x","%");
				documentnumber=documentnumber.replace("X","%");
			}
		}
        Long allocationidValue=null;
        if (!StringUtils.isNullOrBlank(allocationid)){
            allocationidValue=StringUtils.getLongValue(allocationid);
		}
        Map<String, Object> map = new HashMap<String, Object>();
        WaveShipHeadDto header=new WaveShipHeadDto();
		List<TwtActAllocationList> details=this.allocationService.queryReadyShippment(containnumber,documentnumber,allocationidValue,documentmode);
		if ((details==null) || (details.size()==0)){
		    header.setReturestate("E");
		    header.setReturetext("找不到发运记录.托盘码:"+containnumber);
            map.put("header", header);
			return resultError(501, "找不到发运记录.");
		}
        details = this.wasCustomWorkService.livePickFilter(containnumber, details);

		List<WaveShipLineDto> lines=new ArrayList<WaveShipLineDto>();
		this.wasCustomWorkService.populate(header,lines,details);

        header.setReturestate("S");
        header.setReturetext("");
		map.put("header", header);
		map.put("lines", lines);
		return resultOk("读取发运数据成功", Arrays.asList(map));
	}


	/**
	@JsonView(value = { PageResult.View.class })
	@ApiOperation("发运")
	@GetMapping("/save")
	public Result save(@ApiParam(name = "palletnumber") @RequestParam(name = "palletnumber", required=true) String palletnumber,
			@ApiParam(name = "usercode") @RequestParam(name = "usercode", required=false) String usercode) {

		if (StringUtils.isNullOrBlank(palletnumber)){
			return resultError(501, "请指定托盘码");
		}
		List<TwtActAllocationList> details=this.allocationService.queryReadyShippment(palletnumber);
		if ((details==null) || (details.size()==0)){
			return resultError(501, "找不到发运记录,请联系系统管理员");
		}
		TwtActAllocationList allocate=null;
		for(TwtActAllocationList a:details){
			if (a==null){
				continue;
			}
			if (a.getStatus().compareTo(WmsConstants.SO_STATUS_SHIP)>=0){
				continue;
			}
			allocate=a;
			break;
		}
		String msg=this.allocationService.shipment(allocate.getId(), palletnumber);
		if (msg==null){
			return resultError(501, "发运失败.");
		}
		if (!msg.equals(CodesConstants.COMMON_STATUS_SUCCESS)){
			return resultError(501, "发运失败:"+msg);
		}
		return resultOk("发运成功");
	}
    **/

	@JsonView(value = { PageResult.View.class })
	@ApiOperation("确认发货")
	@GetMapping("/confirm")
	public Result confirm(@ApiParam(name = "allocationid") @RequestParam(name = "allocationid", required=true) Long allocationid,
                       @ApiParam(name = "containnumber") @RequestParam(name = "containnumber", required=false) String containnumber,
                       @ApiParam(name = "materialcode") @RequestParam(name = "checkmaterialcode", required=false) String materialcode,
                       @ApiParam(name = "quantity") @RequestParam(name = "quantity", required=false) BigDecimal quantity,
                       @ApiParam(name = "checkmaterialcode") @RequestParam(name = "checkmaterialcode", required=false) String checkmaterialcode,
                       @ApiParam(name = "lostquantity") @RequestParam(name = "lostquantity", required=false) String lostquantity,
                       @ApiParam(name = "documentnumber") @RequestParam(name = "documentnumber", required=false) String documentnumber,
                       @ApiParam(name = "shiptype") @RequestParam(name = "shiptype", required=false) String shiptype,
                       @ApiParam(name = "shipmode") @RequestParam(name = "shipmode", required=false) String shipmode,
					   @ApiParam(name = "usercode") @RequestParam(name = "usercode", required=false) String usercode) {

	    if (StringUtils.isNullOrBlank(shiptype)){
            shiptype= WmsConstants.SHIP_ACTION_SHIP;
        }

        LocationLineDto loc=this.wasCustomWorkService.currentLocation(containnumber);
	    //
        // String m=this.wasCustomWorkService.shipmentByContainerNumber(containnumber, SecurityUtils.getLoginUsername());
        String m=this.wasCustomWorkService.shipmentByAllocationId(allocationid, containnumber, SecurityUtils.getLoginUsername());
	    if (!StringUtils.isNullOrBlank(m)){
            return resultError(501, "发货失败."+m);
        }
        if ((!StringUtils.isNullOrBlank(lostquantity)) && (lostquantity.equalsIgnoreCase("0"))
                && (lostquantity.equalsIgnoreCase("0.0"))){
            this.wasCustomWorkService.saveShiplostInfo(allocationid, lostquantity, SecurityUtils.getLoginUsername());
        }

        //创建空托盘库存/默认
		this.wasCustomWorkService.acceptEpal(containnumber, null, "", loc.getLocationCode(), "");

	    if (!WmsConstants.LOCATION_TYPE_BIN.equalsIgnoreCase(loc.getLocationType())){
            this.wcsCustomWorkService.showPickingTask(loc.getDivisionId(),containnumber,loc.getLocationCode());
        }
	    /**
        if (shiptype.equals(WmsConstants.SHIP_ACTION_TYPE_ALLOCATION)){
            if (StringUtils.isNullOrBlank(allocationid)){
                return resultError(501, "请选中拣货行号");
            }
            m=this.allocationService.shippingAllocation(Long.valueOf(allocationid),"");
        }
        if (shiptype.equals(WmsConstants.SHIP_ACTION_TYPE_CONTAIN)){
            if (StringUtils.isNullOrBlank(palletnumber)){
                return resultError(501, "请指定托盘码");
            }
            m=this.allocationService.shippingContain(palletnumber,"");
        }
        if (shiptype.equals(WmsConstants.SHIP_ACTION_TYPE_SO)){
            if (StringUtils.isNullOrBlank(documentnumber)){
                return resultError(501, "请指定单号");
            }
            m=this.allocationService.shippingSo(palletnumber,"");
        }
		if (m==null){
			return resultError(501, "发运失败.");
		}
		if (!m.equals(CodesConstants.COMMON_STATUS_SUCCESS)){
			return resultError(501, "发运失败:"+m);
		}
         **/
		return resultOk("发运成功");
	}


    private SoStorageShipMatchDto fill(TwaDocWaveHeader header, TwaDocWaveDetails line, TwaInventoryDetails storage){
        SoStorageShipMatchDto matchDto=null;
        if (header==null){
            return matchDto;
        }
        if (line==null){
            return matchDto;
        }
        if (storage==null){
            return matchDto;
        }
        matchDto=new SoStorageShipMatchDto();
        matchDto.setDocid(header.getId());
        matchDto.setDocdetailsid(line.getId());
        matchDto.setStorageid(storage.getId());

        matchDto.setDocumentnumber(header.getDocumentNumber());
        matchDto.setDocumenttype(header.getType());
        matchDto.setDocumentlinenumber(line.getLineNumber());
        matchDto.setRefdocumentnumber(header.getRefDocNumber());
        matchDto.setDocumentstatus(header.getStatus());
        matchDto.setDocumentlinestatus(line.getLineStatus());

        matchDto.setMaterialid(line.getMaterialId());
        matchDto.setMaterialcode(line.getMaterialCode());
        matchDto.setMaterialname(line.getMaterialName());
        matchDto.setChecklotnumber(line.getLotattr05());
        matchDto.setQtyordered(line.getQtyOrdered());
        matchDto.setQtyorderedeach(matchDto.getQtyordered());
        matchDto.setQtyallocated(line.getQtyAllocated());
        matchDto.setQtyallocatedeach(matchDto.getQtyallocated());
        matchDto.setQtypicked(line.getQtyPicked());
        matchDto.setQtypickedeach(matchDto.getQtypicked());
        matchDto.setQtychecked(line.getQtyChecked());
        matchDto.setQtycheckedeach(matchDto.getQtychecked());
        matchDto.setQtyloaded(BigDecimal.ZERO);
        matchDto.setQtyloadedeach(matchDto.getQtyloaded());
        matchDto.setQtyshipped(line.getQtyShipped());
        matchDto.setQtyshippedeach(matchDto.getQtyshipped());

        //
        matchDto.setLotnumber(storage.getLotNumber());
        matchDto.setLocationcode(storage.getLocCode());
        matchDto.setTracenumber(storage.getTraceNumber());
        matchDto.setContainnumber(storage.getContainNumber());
        matchDto.setQuantity(storage.getQty());
        matchDto.setQuantityallocated(storage.getQtyAllocated());
        matchDto.setQualitycstatus(storage.getQualityStatus());
        matchDto.setProductiondate("");
        matchDto.setReceivedate("");
        matchDto.setExpiredate("");
        if(storage.getReceiveTime()!=null){
            matchDto.setReceivedate(DateUtils.format(storage.getReceiveTime(),DateUtils.FORMAT_DATE_YYYY_MM_DD_HH_MM_SS));
        }
        if(storage.getExpireDate()!=null){
            matchDto.setExpiredate(DateUtils.format(storage.getExpireDate(),DateUtils.FORMAT_DATE_YYYY_MM_DD_HH_MM_SS));
        }
        matchDto.setLotnoid(storage.getLotnoId());
        matchDto.setLotnumid(storage.getLotnumId());
        matchDto.setNotes(storage.getNotes());
        return matchDto;
    }
}
